package com.dynaBlaster.elements;

import com.dynaBlaster.core.Direction;
import com.dynaBlaster.core.Point;
import com.dynaBlaster.game.Game;
import com.dynaBlaster.game.GameConfig;
import com.dynaBlaster.view.BoardView;
import com.dynaBlaster.view.GameView;

import android.content.res.Resources;
import android.graphics.drawable.Drawable;

public class Hero extends Creature {

	public Direction dir;   // kierunek ruchu
	
	Direction secondaryDir = Direction.EAST;
	int bombCount = 0;
	private Bomb justPlantedBomb;
	public Point moveDir = new Point();
	public Point steering = new Point();
	
	
	public Hero(Game game) {
		super(game);

		speed = GameConfig.TILE_SIZE / GameConfig.HERO_SPEED_FACTOR;

		IS_FLYING = false;
		IS_PASSING_CREATURES = true;



	}

	/*
	 * Sprawdza czy ruch w kierunku dir dozwolony.
	 * W alt zwraca preferowany ruch alternatywny. 
	 */
	boolean checkDir(Point dir, Point alt) {
		if (dir.nonzero()) {
			boolean freeR, freeL;
			Point r, l, edge_center;
			
			edge_center = pos.add(dir.mul(speed)).add(dir);
			r = dir.rotate90( 1);
			l = dir.rotate90(-1);
			
			freeR = checkFree( edge_center.add(r) );   // check right corner
			freeL = checkFree( edge_center.add(l) );   // check left corner
			
			if (freeR && freeL) { 
				if (alt != null) alt.set(Point.ZERO);
				return true;
			}
			if (freeR) { 
				if (alt != null) alt.set(r);
				return false;
			}			
			if (freeL) {
				if (alt != null) alt.set(l);
				return false;
			}
		}		
		if (alt != null) alt.set(Point.ZERO);
		return false;
	}
	
	/*
	 * Zwraca kierunek w ktorym wykonac ruch.
	 */
	Point chooseDir(Point steering, Point facing) {
		Point dirA, dirB;
		Point altA = new Point(), altB = new Point();
		
		
		// prefer left and right turns
		if (facing.x != 0) {
			dirA = steering.projY();
			dirB = steering.projX();
		}
		else {
			dirB = steering.projY();
			dirA = steering.projX();
		}
		
		// check dirs, save alternatives
		if (checkDir(dirA, altA)) return dirA;
		if (checkDir(dirB, altB)) return dirA;
		
		// check alternatives
		if (checkDir(altA, null)) return altA;
		if (checkDir(altB, null)) return altB;
				
		// can't move in provided directions
		return Point.ZERO;
	}	


	@Override
	public void move() {
		
		// listen & decide
		Point dir = chooseDir(this.steering, this.dir.asPoint());
		
		// update
		pos = pos.add(dir.mul(speed));
		
		/*
		Point next = checkMoveInDirection(dir);
		if (next == null) {// check secondary
			next = checkMoveInDirection(secondaryDir);
		}

		if (next == null) {
			return; // stay
		}

		this.pos = next; // move

		// zchodzenie z nowo postawionej bomby
		if (justPlantedBomb != null && (!justPlantedBomb.isOverPoint(next))) {
			this.justPlantedBomb = null;
		}
		*/
	}

	
	public void setHeroDirections(Direction[] directions) {
		this.dir = directions[0];
		this.secondaryDir = directions[1];
		
		Point a, b;
		
		a = directions[0].asPoint();
		b = directions[1].asPoint();
		
		this.steering = a.add(b);
			
	}

	@Override
	protected boolean checkFree(Point toCheck) {
		return board.isFree(toCheck, IS_PASSING_CREATURES, IS_FLYING);
	}

	public void incrementBombCount() {
		bombCount++;
	}

	public void decrementBombCount() {
		bombCount--;
	}

	public boolean canPlantBomb() {
		return bombCount < GameConfig.HERO_BOMB_COUNT;
	}

	/**
	 * hero moze poruszac sie po bombie ktora wlasnie postawil, dopoki z niej
	 * nie zejdzie bez tej opcji bloowalby sie stawiajac bomby
	 * 
	 * @param bomb
	 */
	public void setJustPlantedBomb(Bomb bomb) {
		this.justPlantedBomb = bomb;

	}

}
